ಆಧುನಿಕ ಪ್ರಕಾರದ ಸಿಸ್ಟಮ್ಗಳ ಒಳ ಕಾರ್ಯಗಳನ್ನು ಅನ್ವೇಷಿಸಿ. ಸುರಕ್ಷಿತ, ಹೆಚ್ಚು ದೃಢವಾದ ಕೋಡ್ಗಾಗಿ ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆ (CFA) ಹೇಗೆ ಶಕ್ತಿಯುತ ಪ್ರಕಾರದ ಕಿರಿದಾಗಿಸುವ ತಂತ್ರಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ತಿಳಿಯಿರಿ.
ಸಂಕಲನಕಾರರು ಹೇಗೆ ಚುರುಕಾಗುತ್ತಾರೆ: ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ ಮತ್ತು ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆಯ ಬಗ್ಗೆ ಆಳವಾದ ಅಧ್ಯಯನ
ಡೆವಲಪರ್ಗಳಾಗಿ, ನಾವು ನಿರಂತರವಾಗಿ ನಮ್ಮ ಪರಿಕರಗಳ ಮೌನ ಬುದ್ಧಿವಂತಿಕೆಯೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸುತ್ತೇವೆ. ನಾವು ಕೋಡ್ ಅನ್ನು ಬರೆಯುತ್ತೇವೆ ಮತ್ತು ನಮ್ಮ IDE ತಕ್ಷಣವೇ ಒಂದು ವಸ್ತುವಿನ ಮೇಲೆ ಲಭ್ಯವಿರುವ ವಿಧಾನಗಳನ್ನು ತಿಳಿದುಕೊಳ್ಳುತ್ತದೆ. ನಾವು ವೇರಿಯೇಬಲ್ ಅನ್ನು ರಿಫ್ಯಾಕ್ಟರ್ ಮಾಡುತ್ತೇವೆ ಮತ್ತು ನಾವು ಫೈಲ್ ಅನ್ನು ಉಳಿಸುವ ಮೊದಲು ಟೈಪ್ ಚೆಕರ್ ಸಂಭಾವ್ಯ ರನ್ಟೈಮ್ ದೋಷದ ಬಗ್ಗೆ ನಮಗೆ ಎಚ್ಚರಿಕೆ ನೀಡುತ್ತದೆ. ಇದು ಮ್ಯಾಜಿಕ್ ಅಲ್ಲ; ಇದು ಅತ್ಯಾಧುನಿಕ ಸ್ಥಿರ ವಿಶ್ಲೇಷಣೆಯ ಫಲಿತಾಂಶವಾಗಿದೆ, ಮತ್ತು ಅದರ ಅತ್ಯಂತ ಶಕ್ತಿಯುತ ಮತ್ತು ಬಳಕೆದಾರ ಸ್ನೇಹಿ ವೈಶಿಷ್ಟ್ಯವೆಂದರೆ ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ.
ನೀವು ಎಂದಾದರೂ string ಅಥವಾ number ಆಗಿರಬಹುದಾದ ವೇರಿಯೇಬಲ್ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಿದ್ದೀರಾ? ಕಾರ್ಯಾಚರಣೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಮೊದಲು ಅದರ ಪ್ರಕಾರವನ್ನು ಪರಿಶೀಲಿಸಲು ನೀವು ಹೆಚ್ಚಾಗಿ if ಹೇಳಿಕೆಯನ್ನು ಬರೆದಿರುತ್ತೀರಿ. ಆ ಬ್ಲಾಕ್ನಲ್ಲಿ, ಭಾಷೆಗೆ ವೇರಿಯೇಬಲ್ string ಎಂದು 'ತಿಳಿದಿತ್ತು', ಇದು ಸ್ಟ್ರಿಂಗ್-ನಿರ್ದಿಷ್ಟ ವಿಧಾನಗಳನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಉದಾಹರಣೆಗೆ, ಸಂಖ್ಯೆಯಲ್ಲಿ .toUpperCase() ಅನ್ನು ಕರೆಯಲು ಪ್ರಯತ್ನಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ. ನಿರ್ದಿಷ್ಟ ಕೋಡ್ ಮಾರ್ಗದಲ್ಲಿ ಪ್ರಕಾರದ ಆ ಬುದ್ಧಿವಂತ ಪರಿಷ್ಕರಣೆಯೇ ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ.
ಆದರೆ ಕಂಪೈಲರ್ ಅಥವಾ ಟೈಪ್ ಚೆಕರ್ ಇದನ್ನು ಹೇಗೆ ಸಾಧಿಸುತ್ತದೆ? ಪ್ರಮುಖ ಕಾರ್ಯವಿಧಾನವೆಂದರೆ ಕಂಪೈಲರ್ ಸಿದ್ಧಾಂತದಿಂದ ಬಂದ ಪ್ರಬಲ ತಂತ್ರ, ಇದನ್ನು ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆ (CFA) ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ. ಈ ಲೇಖನವು ಈ ಪ್ರಕ್ರಿಯೆಯ ಮೇಲಿನ ತೆರೆಯನ್ನು ಎಳೆಯುತ್ತದೆ. ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ ಎಂದರೇನು, ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆ ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ನಾವು ಅನ್ವೇಷಿಸುತ್ತೇವೆ ಮತ್ತು ಪರಿಕಲ್ಪನಾ ಅನುಷ್ಠಾನದ ಮೂಲಕ ನಡೆಯುತ್ತೇವೆ. ಈ ಆಳವಾದ ಅಧ್ಯಯನವು ಕುತೂಹಲಕಾರಿ ಡೆವಲಪರ್, ಮಹತ್ವಾಕಾಂಕ್ಷಿ ಕಂಪೈಲರ್ ಎಂಜಿನಿಯರ್ ಅಥವಾ ಆಧುನಿಕ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಭಾಷೆಗಳನ್ನು ತುಂಬಾ ಸುರಕ್ಷಿತ ಮತ್ತು ಉತ್ಪಾದಕವಾಗಿಸುವ ಅತ್ಯಾಧುನಿಕ ತರ್ಕವನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಬಯಸುವ ಯಾರಿಗಾದರೂ ಆಗಿದೆ.
ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ ಎಂದರೇನು? ಒಂದು ಪ್ರಾಯೋಗಿಕ ಪರಿಚಯ
ಇದರ ಹೃದಯಭಾಗದಲ್ಲಿ, ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ (ಇದನ್ನು ಟೈಪ್ ರಿಫೈನ್ಮೆಂಟ್ ಅಥವಾ ಫ್ಲೋ ಟೈಪಿಂಗ್ ಎಂದೂ ಕರೆಯುತ್ತಾರೆ) ಎನ್ನುವುದು ಸ್ಥಿರ ಟೈಪ್ ಚೆಕರ್ ಒಂದು ನಿರ್ದಿಷ್ಟ ಕೋಡ್ ಪ್ರದೇಶದಲ್ಲಿ ವೇರಿಯೇಬಲ್ಗೆ ಅದರ ಘೋಷಿತ ಪ್ರಕಾರಕ್ಕಿಂತ ಹೆಚ್ಚು ನಿರ್ದಿಷ್ಟವಾದ ಪ್ರಕಾರವನ್ನು ಊಹಿಸುವ ಪ್ರಕ್ರಿಯೆಯಾಗಿದೆ. ಇದು ಯೂನಿಯನ್ನಂತಹ ವಿಶಾಲವಾದ ಪ್ರಕಾರವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ ಮತ್ತು ತಾರ್ಕಿಕ ತಪಾಸಣೆ ಮತ್ತು ಕಾರ್ಯಯೋಜನೆಗಳ ಆಧಾರದ ಮೇಲೆ ಅದನ್ನು 'ಕಿರಿದಾಗಿಸುತ್ತದೆ'.
ಟೈಪ್ಸ್ಕ್ರಿಪ್ಟ್ನ ಸ್ಪಷ್ಟ ಸಿಂಟ್ಯಾಕ್ಸ್ಗಾಗಿ ಕೆಲವು ಸಾಮಾನ್ಯ ಉದಾಹರಣೆಗಳನ್ನು ನೋಡೋಣ, ಆದರೂ ತತ್ವಗಳು ಪೈಥಾನ್ (ಮೈಪಿ), ಕೋಟ್ಲಿನ್ ಮತ್ತು ಇತರ ಅನೇಕ ಆಧುನಿಕ ಭಾಷೆಗಳಿಗೆ ಅನ್ವಯಿಸುತ್ತವೆ.
ಸಾಮಾನ್ಯ ಕಿರಿದಾಗಿಸುವ ತಂತ್ರಗಳು
-
`typeof` ಗಾರ್ಡ್ಗಳು: ಇದು ಅತ್ಯಂತ ಶ್ರೇಷ್ಠ ಉದಾಹರಣೆಯಾಗಿದೆ. ನಾವು ವೇರಿಯೇಬಲ್ನ ಪ್ರಾಚೀನ ಪ್ರಕಾರವನ್ನು ಪರಿಶೀಲಿಸುತ್ತೇವೆ.
ಉದಾಹರಣೆ:
function processInput(input: string | number) {
if (typeof input === 'string') {
// ಈ ಬ್ಲಾಕ್ನ ಒಳಗೆ, 'input' ಎಂಬುದು ಸ್ಟ್ರಿಂಗ್ ಎಂದು ತಿಳಿದಿದೆ.
console.log(input.toUpperCase()); // ಇದು ಸುರಕ್ಷಿತವಾಗಿದೆ!
} else {
// ಈ ಬ್ಲಾಕ್ನ ಒಳಗೆ, 'input' ಎಂಬುದು ಸಂಖ್ಯೆ ಎಂದು ತಿಳಿದಿದೆ.
console.log(input.toFixed(2)); // ಇದು ಸಹ ಸುರಕ್ಷಿತವಾಗಿದೆ!
}
} -
`instanceof` ಗಾರ್ಡ್ಗಳು: ಅವುಗಳ ಕನ್ಸ್ಟ್ರಕ್ಟರ್ ಫಂಕ್ಷನ್ ಅಥವಾ ವರ್ಗದ ಆಧಾರದ ಮೇಲೆ ಆಬ್ಜೆಕ್ಟ್ ಪ್ರಕಾರಗಳನ್ನು ಕಿರಿದಾಗಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ.
ಉದಾಹರಣೆ:
class User { constructor(public name: string) {} }
class Guest { constructor() {} }
function greet(person: User | Guest) {
if (person instanceof User) {
// 'person' ಅನ್ನು User ಪ್ರಕಾರಕ್ಕೆ ಕಿರಿದಾಗಿಸಲಾಗಿದೆ.
console.log(`Hello, ${person.name}!`);
} else {
// 'person' ಅನ್ನು Guest ಪ್ರಕಾರಕ್ಕೆ ಕಿರಿದಾಗಿಸಲಾಗಿದೆ.
console.log('Hello, guest!');
}
} -
ಸತ್ಯಾಸತ್ಯತೆಯ ಪರಿಶೀಲನೆಗಳು: `null`, `undefined`, `0`, `false` ಅಥವಾ ಖಾಲಿ ಸ್ಟ್ರಿಂಗ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಲು ಸಾಮಾನ್ಯ ಮಾದರಿ.
ಉದಾಹರಣೆ:
function printName(name: string | null | undefined) {
if (name) {
// 'name' ಅನ್ನು 'string | null | undefined' ನಿಂದ 'string' ಗೆ ಕಿರಿದಾಗಿಸಲಾಗಿದೆ.
console.log(name.length);
}
} -
ಸಮಾನತೆ ಮತ್ತು ಆಸ್ತಿ ಗಾರ್ಡ್ಗಳು: ನಿರ್ದಿಷ್ಟ ಅಕ್ಷರಶಃ ಮೌಲ್ಯಗಳನ್ನು ಪರಿಶೀಲಿಸುವುದು ಅಥವಾ ಆಸ್ತಿಯ ಅಸ್ತಿತ್ವವನ್ನು ಪರಿಶೀಲಿಸುವುದು ಸಹ ಪ್ರಕಾರಗಳನ್ನು ಕಿರಿದಾಗಿಸಬಹುದು, ವಿಶೇಷವಾಗಿ ತಾರತಮ್ಯದ ಯೂನಿಯನ್ಗಳೊಂದಿಗೆ.
ಉದಾಹರಣೆ (ತಾರತಮ್ಯದ ಯೂನಿಯನ್):
interface Circle { kind: 'circle'; radius: number; }
interface Square { kind: 'square'; sideLength: number; }
type Shape = Circle | Square;
function getArea(shape: Shape) {
if (shape.kind === 'circle') {
// 'shape' ಅನ್ನು Circle ಗೆ ಕಿರಿದಾಗಿಸಲಾಗಿದೆ.
return Math.PI * shape.radius ** 2;
} else {
// 'shape' ಅನ್ನು Square ಗೆ ಕಿರಿದಾಗಿಸಲಾಗಿದೆ.
return shape.sideLength ** 2;
}
}
ಪ್ರಯೋಜನ ಅಪಾರವಾಗಿದೆ. ಇದು ಕಂಪೈಲ್-ಸಮಯದ ಸುರಕ್ಷತೆಯನ್ನು ಒದಗಿಸುತ್ತದೆ, ರನ್ಟೈಮ್ ದೋಷಗಳ ದೊಡ್ಡ ವರ್ಗವನ್ನು ತಡೆಯುತ್ತದೆ. ಇದು ಉತ್ತಮ ಸ್ವಯಂಪೂರ್ಣತೆಯೊಂದಿಗೆ ಡೆವಲಪರ್ ಅನುಭವವನ್ನು ಸುಧಾರಿಸುತ್ತದೆ ಮತ್ತು ಕೋಡ್ ಅನ್ನು ಹೆಚ್ಚು ಸ್ವಯಂ-ದಾಖಲೀಕರಣ ಮಾಡುತ್ತದೆ. ಪ್ರಶ್ನೆಯೆಂದರೆ, ಟೈಪ್ ಚೆಕರ್ ಈ ಸಂದರ್ಭೋಚಿತ ಜಾಗೃತಿಯನ್ನು ಹೇಗೆ ನಿರ್ಮಿಸುತ್ತದೆ?
ಮ್ಯಾಜಿಕ್ನ ಹಿಂದಿನ ಎಂಜಿನ್: ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆಯನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು (CFA)
ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆಯು ಸ್ಥಿರ ವಿಶ್ಲೇಷಣೆಯ ತಂತ್ರವಾಗಿದ್ದು, ಇದು ಕಂಪೈಲರ್ ಅಥವಾ ಟೈಪ್ ಚೆಕರ್ಗೆ ಪ್ರೋಗ್ರಾಂ ತೆಗೆದುಕೊಳ್ಳಬಹುದಾದ ಸಂಭಾವ್ಯ ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮಾರ್ಗಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದು ಕೋಡ್ ಅನ್ನು ರನ್ ಮಾಡುವುದಿಲ್ಲ; ಇದು ಅದರ ರಚನೆಯನ್ನು ವಿಶ್ಲೇಷಿಸುತ್ತದೆ. ಇದಕ್ಕಾಗಿ ಬಳಸಲಾಗುವ ಪ್ರಾಥಮಿಕ ಡೇಟಾ ರಚನೆಯೆಂದರೆ ನಿಯಂತ್ರಣ ಹರಿವಿನ ಗ್ರಾಫ್ (CFG).
ನಿಯಂತ್ರಣ ಹರಿವಿನ ಗ್ರಾಫ್ (CFG) ಎಂದರೇನು?
CFG ಎಂಬುದು ನಿರ್ದೇಶಿತ ಗ್ರಾಫ್ ಆಗಿದ್ದು, ಪ್ರೋಗ್ರಾಂನ ಕಾರ್ಯಗತಗೊಳಿಸುವ ಸಮಯದಲ್ಲಿ ಹಾದುಹೋಗಬಹುದಾದ ಎಲ್ಲಾ ಸಂಭಾವ್ಯ ಮಾರ್ಗಗಳನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತದೆ. ಇದು ಇವುಗಳಿಂದ ಕೂಡಿದೆ:
- ನೋಡ್ಗಳು (ಅಥವಾ ಮೂಲ ಬ್ಲಾಕ್ಗಳು): ಪ್ರಾರಂಭ ಮತ್ತು ಅಂತ್ಯದಲ್ಲಿ ಹೊರತುಪಡಿಸಿ, ಒಳಗೆ ಅಥವಾ ಹೊರಗೆ ಯಾವುದೇ ಶಾಖೆಗಳಿಲ್ಲದ ಸತತ ಹೇಳಿಕೆಗಳ ಅನುಕ್ರಮ. ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯು ಯಾವಾಗಲೂ ಬ್ಲಾಕ್ನ ಮೊದಲ ಹೇಳಿಕೆಯಲ್ಲಿ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ ಮತ್ತು ಸ್ಥಗಿತಗೊಳಿಸದೆ ಅಥವಾ ಶಾಖೆ ನೀಡದೆ ಕೊನೆಯದಕ್ಕೆ ಮುಂದುವರಿಯುತ್ತದೆ.
- ಅಂಚುಗಳು: ಇವು ನಿಯಂತ್ರಣದ ಹರಿವನ್ನು ಅಥವಾ ಮೂಲ ಬ್ಲಾಕ್ಗಳ ನಡುವಿನ 'ಜಿಗಿತಗಳನ್ನು' ಪ್ರತಿನಿಧಿಸುತ್ತವೆ. ಉದಾಹರಣೆಗೆ, `if` ಹೇಳಿಕೆಯು ಎರಡು ಹೊರಹೋಗುವ ಅಂಚುಗಳನ್ನು ಹೊಂದಿರುವ ನೋಡ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ: ಒಂದು 'ನಿಜ' ಮಾರ್ಗಕ್ಕೆ ಮತ್ತು ಒಂದು 'ತಪ್ಪು' ಮಾರ್ಗಕ್ಕೆ.
ಸರಳವಾದ `if-else` ಹೇಳಿಕೆಗಾಗಿ CFG ಅನ್ನು ದೃಶ್ಯೀಕರಿಸೋಣ:
let x: string | number = ...;
if (typeof x === 'string') { // ಬ್ಲಾಕ್ A (ಷರತ್ತು)
console.log(x.length); // ಬ್ಲಾಕ್ B (ನಿಜ ಶಾಖೆ)
} else {
console.log(x + 1); // ಬ್ಲಾಕ್ C (ತಪ್ಪು ಶಾಖೆ)
}
console.log('Done'); // ಬ್ಲಾಕ್ D (ವಿಲೀನ ಬಿಂದು)
ಪರಿಕಲ್ಪನಾತ್ಮಕ CFG ಈ ರೀತಿ ಕಾಣುತ್ತದೆ:
[ ಪ್ರವೇಶ ] --> [ ಬ್ಲಾಕ್ A: `typeof x === 'string'` ] --> (ನಿಜವಾದ ಅಂಚು) --> [ ಬ್ಲಾಕ್ B ] --> [ ಬ್ಲಾಕ್ D ]
\-> (ತಪ್ಪಾದ ಅಂಚು) --> [ ಬ್ಲಾಕ್ C ] --/
CFA ಈ ಗ್ರಾಫ್ ಅನ್ನು 'ನಡೆಯುವುದು' ಮತ್ತು ಪ್ರತಿ ನೋಡ್ನಲ್ಲಿ ಮಾಹಿತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡುವುದನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆಗಾಗಿ, ನಾವು ಟ್ರ್ಯಾಕ್ ಮಾಡುವ ಮಾಹಿತಿಯು ಪ್ರತಿ ವೇರಿಯೇಬಲ್ಗೆ ಸಂಭಾವ್ಯ ಪ್ರಕಾರಗಳ ಗುಂಪಾಗಿದೆ. ಅಂಚುಗಳ ಮೇಲಿನ ಷರತ್ತುಗಳನ್ನು ವಿಶ್ಲೇಷಿಸುವ ಮೂಲಕ, ನಾವು ಬ್ಲಾಕ್ನಿಂದ ಬ್ಲಾಕ್ಗೆ ಚಲಿಸುವಾಗ ಈ ಪ್ರಕಾರದ ಮಾಹಿತಿಯನ್ನು ನವೀಕರಿಸಬಹುದು.
ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆಗಾಗಿ ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು: ಒಂದು ಪರಿಕಲ್ಪನಾ ನಡಿಗೆ
ಕಿರಿದಾಗಿಸುವಿಕೆಗಾಗಿ CFA ಅನ್ನು ಬಳಸುವ ಟೈಪ್ ಚೆಕರ್ ಅನ್ನು ನಿರ್ಮಿಸುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು ವಿಶ್ಲೇಷಿಸೋಣ. ರಸ್ಟ್ ಅಥವಾ C++ ನಂತಹ ಭಾಷೆಯಲ್ಲಿನ ನೈಜ-ಪ್ರಪಂಚದ ಅನುಷ್ಠಾನವು ನಂಬಲಾಗದಷ್ಟು ಸಂಕೀರ್ಣವಾಗಿದ್ದರೂ, ಪ್ರಮುಖ ಪರಿಕಲ್ಪನೆಗಳು ಅರ್ಥವಾಗುವಂತಹದ್ದಾಗಿವೆ.
ಹಂತ 1: ನಿಯಂತ್ರಣ ಹರಿವಿನ ಗ್ರಾಫ್ ಅನ್ನು ನಿರ್ಮಿಸುವುದು (CFG)
ಯಾವುದೇ ಕಂಪೈಲರ್ಗೆ ಮೊದಲ ಹಂತವೆಂದರೆ ಸೋರ್ಸ್ ಕೋಡ್ ಅನ್ನು ಅಮೂರ್ತ ಸಿಂಟ್ಯಾಕ್ಸ್ ಟ್ರೀ (AST) ಆಗಿ ಪಾರ್ಸ್ ಮಾಡುವುದು. AST ಕೋಡ್ನ ಸಿಂಟ್ಯಾಕ್ಸ್ ರಚನೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತದೆ. CFG ಅನ್ನು ನಂತರ ಈ AST ಯಿಂದ ನಿರ್ಮಿಸಲಾಗಿದೆ.
CFG ಅನ್ನು ನಿರ್ಮಿಸುವ ಅಲ್ಗಾರಿದಮ್ ಸಾಮಾನ್ಯವಾಗಿ ಒಳಗೊಂಡಿರುತ್ತದೆ:
- ಮೂಲ ಬ್ಲಾಕ್ ನಾಯಕರನ್ನು ಗುರುತಿಸುವುದು: ಹೇಳಿಕೆಯು ನಾಯಕನಾಗಿದ್ದರೆ (ಹೊಸ ಮೂಲ ಬ್ಲಾಕ್ನ ಪ್ರಾರಂಭ), ಅದು ಹೀಗಿರಬೇಕು:
- ಪ್ರೋಗ್ರಾಂನಲ್ಲಿ ಮೊದಲ ಹೇಳಿಕೆ.
- ಶಾಖೆಯ ಗುರಿ (ಉದಾಹರಣೆಗೆ, `if` ಅಥವಾ `else` ಬ್ಲಾಕ್ನೊಳಗಿನ ಕೋಡ್, ಲೂಪ್ನ ಪ್ರಾರಂಭ).
- ಶಾಖೆ ಅಥವಾ ರಿಟರ್ನ್ ಹೇಳಿಕೆಯ ತಕ್ಷಣದ ನಂತರದ ಹೇಳಿಕೆ.
- ಬ್ಲಾಕ್ಗಳನ್ನು ನಿರ್ಮಿಸುವುದು: ಪ್ರತಿ ನಾಯಕನಿಗೆ, ಅದರ ಮೂಲ ಬ್ಲಾಕ್ ನಾಯಕನನ್ನು ಮತ್ತು ನಂತರದ ಎಲ್ಲಾ ಹೇಳಿಕೆಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ, ಮುಂದಿನ ನಾಯಕನನ್ನು ಹೊರತುಪಡಿಸಿ.
- ಅಂಚುಗಳನ್ನು ಸೇರಿಸುವುದು: ಹರಿವನ್ನು ಪ್ರತಿನಿಧಿಸಲು ಬ್ಲಾಕ್ಗಳ ನಡುವೆ ಅಂಚುಗಳನ್ನು ಎಳೆಯಲಾಗುತ್ತದೆ. `if (condition)` ನಂತಹ ಷರತ್ತುಬದ್ಧ ಹೇಳಿಕೆಯು ಷರತ್ತಿನ ಬ್ಲಾಕ್ನಿಂದ 'ನಿಜವಾದ' ಬ್ಲಾಕ್ಗೆ ಅಂಚನ್ನು ಮತ್ತು 'ತಪ್ಪಾದ' ಬ್ಲಾಕ್ಗೆ ಇನ್ನೊಂದನ್ನು ರಚಿಸುತ್ತದೆ (`else` ಇಲ್ಲದಿದ್ದರೆ ತಕ್ಷಣದ ನಂತರದ ಬ್ಲಾಕ್).
ಹಂತ 2: ರಾಜ್ಯದ ಸ್ಥಳ - ಪ್ರಕಾರದ ಮಾಹಿತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡುವುದು
ವಿಶ್ಲೇಷಕವು CFG ಅನ್ನು ಹಾದುಹೋದಾಗ, ಅದು ಪ್ರತಿ ಹಂತದಲ್ಲಿ 'ರಾಜ್ಯ'ವನ್ನು ನಿರ್ವಹಿಸಬೇಕಾಗುತ್ತದೆ. ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆಗಾಗಿ, ಈ ರಾಜ್ಯವು ಮೂಲಭೂತವಾಗಿ ನಕ್ಷೆ ಅಥವಾ ನಿಘಂಟಾಗಿದ್ದು, ವ್ಯಾಪ್ತಿಯಲ್ಲಿರುವ ಪ್ರತಿಯೊಂದು ವೇರಿಯೇಬಲ್ ಅನ್ನು ಅದರ ಪ್ರಸ್ತುತ, ಸಂಭಾವ್ಯವಾಗಿ ಕಿರಿದಾದ ಪ್ರಕಾರದೊಂದಿಗೆ ಸಂಯೋಜಿಸುತ್ತದೆ.
// ಕೋಡ್ನಲ್ಲಿ ನೀಡಲಾದ ಹಂತದಲ್ಲಿ ಪರಿಕಲ್ಪನಾತ್ಮಕ ಸ್ಥಿತಿ
interface TypeState {
[variableName: string]: Type;
}
ಕಾರ್ಯ ಅಥವಾ ಪ್ರೋಗ್ರಾಂನ ಪ್ರವೇಶ ಬಿಂದುವಿನಲ್ಲಿ ವಿಶ್ಲೇಷಣೆಯು ಪ್ರಾರಂಭವಾಗುತ್ತದೆ, ಅಲ್ಲಿ ಪ್ರತಿಯೊಂದು ವೇರಿಯೇಬಲ್ ತನ್ನ ಘೋಷಿತ ಪ್ರಕಾರವನ್ನು ಹೊಂದಿರುತ್ತದೆ. ನಮ್ಮ ಹಿಂದಿನ ಉದಾಹರಣೆಗಾಗಿ, ಆರಂಭಿಕ ಸ್ಥಿತಿಯು ಹೀಗಿರುತ್ತದೆ: { x: String | Number }. ಈ ಸ್ಥಿತಿಯನ್ನು ನಂತರ ಗ್ರಾಫ್ ಮೂಲಕ ಹರಡಲಾಗುತ್ತದೆ.
ಹಂತ 3: ಷರತ್ತುಬದ್ಧ ಗಾರ್ಡ್ಗಳನ್ನು ವಿಶ್ಲೇಷಿಸುವುದು (ಪ್ರಮುಖ ತರ್ಕ)
ಇಲ್ಲಿಯೇ ಕಿರಿದಾಗಿಸುವಿಕೆ ನಡೆಯುತ್ತದೆ. ವಿಶ್ಲೇಷಕವು ಷರತ್ತುಬದ್ಧ ಶಾಖೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುವ ನೋಡ್ ಅನ್ನು ಎದುರಿಸಿದಾಗ (`if`, `while` ಅಥವಾ `switch` ಷರತ್ತು), ಅದು ಷರತ್ತನ್ನು ಪರೀಕ್ಷಿಸುತ್ತದೆ. ಷರತ್ತಿನ ಆಧಾರದ ಮೇಲೆ, ಅದು ಎರಡು ವಿಭಿನ್ನ ಔಟ್ಪುಟ್ ಸ್ಥಿತಿಗಳನ್ನು ರಚಿಸುತ್ತದೆ: ಒಂದು ಷರತ್ತು ನಿಜವಾಗಿರುವ ಮಾರ್ಗಕ್ಕಾಗಿ ಮತ್ತು ಇನ್ನೊಂದು ಅದು ತಪ್ಪಾಗಿರುವ ಮಾರ್ಗಕ್ಕಾಗಿ.
ನಾವು ಗಾರ್ಡ್ typeof x === 'string' ಅನ್ನು ವಿಶ್ಲೇಷಿಸೋಣ:
-
'ನಿಜವಾದ' ಶಾಖೆ: ವಿಶ್ಲೇಷಕವು ಈ ಮಾದರಿಯನ್ನು ಗುರುತಿಸುತ್ತದೆ. ಈ ಅಭಿವ್ಯಕ್ತಿ ನಿಜವಾಗಿದ್ದರೆ, `x` ನ ಪ್ರಕಾರವು `string` ಆಗಿರಬೇಕು ಎಂದು ತಿಳಿದಿದೆ. ಆದ್ದರಿಂದ, ಅದು ತನ್ನ ನಕ್ಷೆಯನ್ನು ನವೀಕರಿಸುವ ಮೂಲಕ 'ನಿಜವಾದ' ಮಾರ್ಗಕ್ಕಾಗಿ ಹೊಸ ಸ್ಥಿತಿಯನ್ನು ರಚಿಸುತ್ತದೆ:
ಇನ್ಪುಟ್ ಸ್ಥಿತಿ:
{ x: String | Number }ನಿಜವಾದ ಮಾರ್ಗಕ್ಕಾಗಿ ಔಟ್ಪುಟ್ ಸ್ಥಿತಿ:
ಈ ಹೊಸ, ಹೆಚ್ಚು ನಿಖರವಾದ ಸ್ಥಿತಿಯನ್ನು ನಂತರ ನಿಜವಾದ ಶಾಖೆಯಲ್ಲಿನ ಮುಂದಿನ ಬ್ಲಾಕ್ಗೆ (ಬ್ಲಾಕ್ B) ಹರಡಲಾಗುತ್ತದೆ. ಬ್ಲಾಕ್ B ಯ ಒಳಗೆ, `x` ಮೇಲಿನ ಯಾವುದೇ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು `String` ಪ್ರಕಾರದ ವಿರುದ್ಧ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ.{ x: String } -
'ತಪ್ಪಾದ' ಶಾಖೆ: ಇದು ಬಹಳ ಮುಖ್ಯ.
typeof x === 'string'ತಪ್ಪಾಗಿದ್ದರೆ, ಅದು `x` ಬಗ್ಗೆ ನಮಗೆ ಏನು ಹೇಳುತ್ತದೆ? ವಿಶ್ಲೇಷಕವು ಮೂಲ ಪ್ರಕಾರದಿಂದ 'ನಿಜವಾದ' ಪ್ರಕಾರವನ್ನು ಕಳೆಯಬಹುದು.ಇನ್ಪುಟ್ ಸ್ಥಿತಿ:
{ x: String | Number }ತೆಗೆದುಹಾಕಬೇಕಾದ ಪ್ರಕಾರ:
Stringತಪ್ಪಾದ ಮಾರ್ಗಕ್ಕಾಗಿ ಔಟ್ಪುಟ್ ಸ್ಥಿತಿ:
ಈ ಪರಿಷ್ಕರಿಸಿದ ಸ್ಥಿತಿಯನ್ನು 'ತಪ್ಪಾದ' ಮಾರ್ಗಕ್ಕೆ ಬ್ಲಾಕ್ C ಗೆ ಹರಡಲಾಗುತ್ತದೆ. ಬ್ಲಾಕ್ C ಯ ಒಳಗೆ, `x` ಅನ್ನು ಸರಿಯಾಗಿ `Number` ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ.{ x: Number }(ಏಕೆಂದರೆ(String | Number) - String = Number)
ವಿಶ್ಲೇಷಕವು ವಿವಿಧ ಮಾದರಿಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಅಂತರ್ಗತ ತರ್ಕವನ್ನು ಹೊಂದಿರಬೇಕು:
x instanceof C: ನಿಜವಾದ ಮಾರ್ಗದಲ್ಲಿ, `x` ನ ಪ್ರಕಾರವು `C` ಆಗುತ್ತದೆ. ತಪ್ಪಾದ ಮಾರ್ಗದಲ್ಲಿ, ಅದು ಅದರ ಮೂಲ ಪ್ರಕಾರವಾಗಿ ಉಳಿಯುತ್ತದೆ.x != null: ನಿಜವಾದ ಮಾರ್ಗದಲ್ಲಿ, `Null` ಮತ್ತು `Undefined` ಅನ್ನು `x` ನ ಪ್ರಕಾರದಿಂದ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ.shape.kind === 'circle': `shape` ಒಂದು ತಾರತಮ್ಯದ ಯೂನಿಯನ್ ಆಗಿದ್ದರೆ, ಅದರ ಪ್ರಕಾರವನ್ನು ಸದಸ್ಯನಿಗೆ ಕಿರಿದಾಗಿಸಲಾಗುತ್ತದೆ, ಅಲ್ಲಿ `kind` ಅಕ್ಷರಶಃ ಪ್ರಕಾರ `'circle'` ಆಗಿದೆ.
ಹಂತ 4: ನಿಯಂತ್ರಣ ಹರಿವಿನ ಮಾರ್ಗಗಳನ್ನು ವಿಲೀನಗೊಳಿಸುವುದು
ಶಾಖೆಗಳು ಮರುಸೇರ್ಪಡೆಯಾದಾಗ ಏನಾಗುತ್ತದೆ, ನಮ್ಮ `if-else` ಹೇಳಿಕೆಯ ನಂತರ ಬ್ಲಾಕ್ D ನಲ್ಲಿರುವಂತೆ? ವಿಶ್ಲೇಷಕವು ಈ ವಿಲೀನ ಬಿಂದುವಿಗೆ ಬರುವ ಎರಡು ವಿಭಿನ್ನ ಸ್ಥಿತಿಗಳನ್ನು ಹೊಂದಿದೆ:
- ಬ್ಲಾಕ್ B ಯಿಂದ (ನಿಜವಾದ ಮಾರ್ಗ):
{ x: String } - ಬ್ಲಾಕ್ C ಯಿಂದ (ತಪ್ಪಾದ ಮಾರ್ಗ):
{ x: Number }
ಬ್ಲಾಕ್ D ನಲ್ಲಿನ ಕೋಡ್ ಯಾವ ಮಾರ್ಗವನ್ನು ತೆಗೆದುಕೊಂಡರೂ ಅದು ಮಾನ್ಯವಾಗಿರಬೇಕು. ಇದನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು, ವಿಶ್ಲೇಷಕವು ಈ ಸ್ಥಿತಿಗಳನ್ನು ವಿಲೀನಗೊಳಿಸಬೇಕು. ಪ್ರತಿ ವೇರಿಯೇಬಲ್ಗೆ, ಅದು ಎಲ್ಲಾ ಸಾಧ್ಯತೆಗಳನ್ನು ಒಳಗೊಂಡಿರುವ ಹೊಸ ಪ್ರಕಾರವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುತ್ತದೆ. ಇದು ಸಾಮಾನ್ಯವಾಗಿ ಎಲ್ಲಾ ಒಳಬರುವ ಮಾರ್ಗಗಳಿಂದ ಪ್ರಕಾರಗಳ ಯೂನಿಯನ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳುವ ಮೂಲಕ ಮಾಡಲಾಗುತ್ತದೆ.
ಬ್ಲಾಕ್ D ಗಾಗಿ ವಿಲೀನಗೊಂಡ ಸ್ಥಿತಿ: { x: Union(String, Number) } ಇದು { x: String | Number } ಗೆ ಸರಳೀಕರಿಸುತ್ತದೆ.
`x` ನ ಪ್ರಕಾರವು ಅದರ ಮೂಲ, ವಿಶಾಲವಾದ ಪ್ರಕಾರಕ್ಕೆ ಮರಳುತ್ತದೆ ಏಕೆಂದರೆ ಪ್ರೋಗ್ರಾಂನಲ್ಲಿ ಈ ಹಂತದಲ್ಲಿ, ಅದು ಯಾವುದೇ ಶಾಖೆಯಿಂದ ಬಂದಿರಬಹುದು. ಅದಕ್ಕಾಗಿಯೇ ನೀವು `if-else` ಬ್ಲಾಕ್ನ ನಂತರ `x.toUpperCase()` ಅನ್ನು ಬಳಸಲಾಗುವುದಿಲ್ಲ - ಪ್ರಕಾರದ ಸುರಕ್ಷತೆಯ ಖಾತರಿ ಹೋಗಿದೆ.
ಹಂತ 5: ಲೂಪ್ಗಳು ಮತ್ತು ಕಾರ್ಯಯೋಜನೆಗಳನ್ನು ನಿರ್ವಹಿಸುವುದು
-
ಕಾರ್ಯಯೋಜನೆಗಳು: ವೇರಿಯೇಬಲ್ಗೆ ಕಾರ್ಯಯೋಜನೆಯು CFA ಗೆ ನಿರ್ಣಾಯಕ ಘಟನೆಯಾಗಿದೆ. ವಿಶ್ಲೇಷಕವು
x = 10;ಅನ್ನು ನೋಡಿದರೆ, ಅದು `x` ಗಾಗಿ ಹೊಂದಿದ್ದ ಯಾವುದೇ ಹಿಂದಿನ ಕಿರಿದಾಗಿಸುವ ಮಾಹಿತಿಯನ್ನು ತಿರಸ್ಕರಿಸಬೇಕು. `x` ನ ಪ್ರಕಾರವು ಈಗ ಖಚಿತವಾಗಿ ನಿಯೋಜಿಸಲಾದ ಮೌಲ್ಯದ ಪ್ರಕಾರವಾಗಿದೆ (`Number` ಈ ಸಂದರ್ಭದಲ್ಲಿ). ಈ ಅಮಾನ್ಯೀಕರಣವು ಸರಿಯಾಗಿರಲು ಬಹಳ ಮುಖ್ಯ. ಡೆವಲಪರ್ ಗೊಂದಲದ ಸಾಮಾನ್ಯ ಮೂಲವೆಂದರೆ ಕಿರಿದಾದ ವೇರಿಯೇಬಲ್ ಅನ್ನು ಮುಚ್ಚುವಿಕೆಯೊಳಗೆ ಮರುನಿಯೋಜಿಸಿದಾಗ, ಅದು ಹೊರಗಿನ ಕಿರಿದಾಗಿಸುವಿಕೆಯನ್ನು ಅಮಾನ್ಯಗೊಳಿಸುತ್ತದೆ. - ಲೂಪ್ಗಳು: ಲೂಪ್ಗಳು CFG ನಲ್ಲಿ ಚಕ್ರಗಳನ್ನು ರಚಿಸುತ್ತವೆ. ಲೂಪ್ನ ವಿಶ್ಲೇಷಣೆ ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗಿದೆ. ವಿಶ್ಲೇಷಕವು ಲೂಪ್ ದೇಹವನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬೇಕು, ನಂತರ ಲೂಪ್ನ ಕೊನೆಯಲ್ಲಿನ ಸ್ಥಿತಿಯು ಪ್ರಾರಂಭದಲ್ಲಿನ ಸ್ಥಿತಿಯನ್ನು ಹೇಗೆ ಪರಿಣಾಮ ಬೀರುತ್ತದೆ ಎಂಬುದನ್ನು ನೋಡಬೇಕು. ಅದು ಲೂಪ್ ದೇಹವನ್ನು ಹಲವು ಬಾರಿ ಮರು-ವಿಶ್ಲೇಷಿಸಬೇಕಾಗಬಹುದು, ಪ್ರತಿ ಬಾರಿ ಪ್ರಕಾರಗಳನ್ನು ಪರಿಷ್ಕರಿಸುತ್ತದೆ, ಪ್ರಕಾರದ ಮಾಹಿತಿಯು ಸ್ಥಿರಗೊಳ್ಳುವವರೆಗೆ - ಈ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಸ್ಥಿರ ಬಿಂದುವನ್ನು ತಲುಪುವುದು ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, `for...of` ಲೂಪ್ನಲ್ಲಿ, ವೇರಿಯೇಬಲ್ನ ಪ್ರಕಾರವನ್ನು ಲೂಪ್ನಲ್ಲಿ ಕಿರಿದಾಗಿಸಬಹುದು, ಆದರೆ ಪ್ರತಿ ಪುನರಾವರ್ತನೆಯೊಂದಿಗೆ ಈ ಕಿರಿದಾಗಿಸುವಿಕೆಯನ್ನು ಮರುಹೊಂದಿಸಲಾಗುತ್ತದೆ.
ಮೂಲಭೂತ ಅಂಶಗಳನ್ನು ಮೀರಿ: ಸುಧಾರಿತ CFA ಪರಿಕಲ್ಪನೆಗಳು ಮತ್ತು ಸವಾಲುಗಳು
ಮೇಲಿನ ಸರಳ ಮಾದರಿಯು ಮೂಲಭೂತ ಅಂಶಗಳನ್ನು ಒಳಗೊಂಡಿದೆ, ಆದರೆ ನೈಜ-ಪ್ರಪಂಚದ ಸನ್ನಿವೇಶಗಳು ಗಮನಾರ್ಹ ಸಂಕೀರ್ಣತೆಯನ್ನು ಪರಿಚಯಿಸುತ್ತವೆ.
ಪ್ರಕಾರದ ಭವಿಷ್ಯವಾಣಿಗಳು ಮತ್ತು ಬಳಕೆದಾರ-ವ್ಯಾಖ್ಯಾನಿತ ಪ್ರಕಾರದ ಗಾರ್ಡ್ಗಳು
ಟೈಪ್ಸ್ಕ್ರಿಪ್ಟ್ನಂತಹ ಆಧುನಿಕ ಭಾಷೆಗಳು ಡೆವಲಪರ್ಗಳಿಗೆ CFA ಸಿಸ್ಟಮ್ಗೆ ಸುಳಿವುಗಳನ್ನು ನೀಡಲು ಅನುಮತಿಸುತ್ತವೆ. ಬಳಕೆದಾರ-ವ್ಯಾಖ್ಯಾನಿತ ಪ್ರಕಾರದ ಗಾರ್ಡ್ ಎನ್ನುವುದು ಒಂದು ಕಾರ್ಯವಾಗಿದೆ, ಇದರ ರಿಟರ್ನ್ ಪ್ರಕಾರವು ವಿಶೇಷ ಪ್ರಕಾರದ ಭವಿಷ್ಯವಾಣಿಯಾಗಿದೆ.
function isUser(obj: any): obj is User {
return obj && typeof obj.name === 'string';
}
ರಿಟರ್ನ್ ಪ್ರಕಾರ obj is User ಟೈಪ್ ಚೆಕರ್ಗೆ ಹೇಳುತ್ತದೆ: "ಈ ಕಾರ್ಯವು `true` ಅನ್ನು ಹಿಂತಿರುಗಿಸಿದರೆ, ನೀವು ವಾದ `obj` ಪ್ರಕಾರ `User` ಎಂದು ಊಹಿಸಬಹುದು."
CFA if (isUser(someVar)) { ... } ಅನ್ನು ಎದುರಿಸಿದಾಗ, ಅದು ಕಾರ್ಯದ ಆಂತರಿಕ ತರ್ಕವನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವ ಅಗತ್ಯವಿಲ್ಲ. ಇದು ಸಹಿಯನ್ನು ನಂಬುತ್ತದೆ. 'ನಿಜವಾದ' ಮಾರ್ಗದಲ್ಲಿ, ಅದು someVar ಅನ್ನು `User` ಗೆ ಕಿರಿದಾಗಿಸುತ್ತದೆ. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನ ಡೊಮೇನ್ಗೆ ನಿರ್ದಿಷ್ಟವಾದ ಹೊಸ ಕಿರಿದಾಗಿಸುವ ಮಾದರಿಗಳನ್ನು ವಿಶ್ಲೇಷಕಕ್ಕೆ ಕಲಿಸಲು ಇದು ವಿಸ್ತರಿಸಬಹುದಾದ ಮಾರ್ಗವಾಗಿದೆ.
ವಿಘಟನೆ ಮತ್ತು ಅಲಿಯಾಸಿಂಗ್ನ ವಿಶ್ಲೇಷಣೆ
ನೀವು ವೇರಿಯೇಬಲ್ಗಳಿಗೆ ಪ್ರತಿಗಳನ್ನು ಅಥವಾ ಉಲ್ಲೇಖಗಳನ್ನು ರಚಿಸಿದಾಗ ಏನಾಗುತ್ತದೆ? CFA ಈ ಸಂಬಂಧಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಸಾಕಷ್ಟು ಸ್ಮಾರ್ಟ್ ಆಗಿರಬೇಕು, ಇದನ್ನು ಅಲಿಯಾಸ್ ವಿಶ್ಲೇಷಣೆ ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ.
const { kind, radius } = shape; // shape is Circle | Square
if (kind === 'circle') {
// ಇಲ್ಲಿ, 'kind' ಅನ್ನು 'circle' ಗೆ ಕಿರಿದಾಗಿಸಲಾಗಿದೆ.
// ಆದರೆ ವಿಶ್ಲೇಷಕನಿಗೆ 'shape' ಈಗ ವೃತ್ತವಾಗಿದೆ ಎಂದು ತಿಳಿದಿದೆಯೇ?
console.log(radius); // TS ನಲ್ಲಿ, ಇದು ವಿಫಲಗೊಳ್ಳುತ್ತದೆ! 'radius' 'shape' ನಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲದಿರಬಹುದು.
}
ಮೇಲಿನ ಉದಾಹರಣೆಯಲ್ಲಿ, ಸ್ಥಳೀಯ ಸ್ಥಿರ kind ಅನ್ನು ಕಿರಿದಾಗಿಸುವುದು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಮೂಲ `shape` ವಸ್ತುವನ್ನು ಕಿರಿದಾಗಿಸುವುದಿಲ್ಲ. ಏಕೆಂದರೆ `shape` ಅನ್ನು ಬೇರೆಡೆ ಮರುನಿಯೋಜಿಸಬಹುದು. ಆದಾಗ್ಯೂ, ನೀವು ಆಸ್ತಿಯನ್ನು ನೇರವಾಗಿ ಪರಿಶೀಲಿಸಿದರೆ, ಅದು ಕೆಲಸ ಮಾಡುತ್ತದೆ:
if (shape.kind === 'circle') {
// ಇದು ಕೆಲಸ ಮಾಡುತ್ತದೆ! CFA ಗೆ 'shape' ಅನ್ನು ಸ್ವತಃ ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ ಎಂದು ತಿಳಿದಿದೆ.
console.log(shape.radius);
}
ಅತ್ಯಾಧುನಿಕ CFA ಕೇವಲ ವೇರಿಯೇಬಲ್ಗಳನ್ನು ಮಾತ್ರವಲ್ಲದೆ ವೇರಿಯೇಬಲ್ಗಳ ಗುಣಲಕ್ಷಣಗಳನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ ಮತ್ತು ಅಲಿಯಾಸ್ ಯಾವಾಗ 'ಸುರಕ್ಷಿತ' ಎಂದು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಬೇಕು (ಉದಾಹರಣೆಗೆ, ಮೂಲ ವಸ್ತುವು `const` ಆಗಿದ್ದರೆ ಮತ್ತು ಅದನ್ನು ಮರುನಿಯೋಜಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ).
ಮುಚ್ಚುವಿಕೆಗಳು ಮತ್ತು ಉನ್ನತ-ಕ್ರಮದ ಕಾರ್ಯಗಳ ಪ್ರಭಾವ
ಕಾರ್ಯಗಳನ್ನು ವಾದಗಳಾಗಿ ರವಾನಿಸಿದಾಗ ಅಥವಾ ಮುಚ್ಚುವಿಕೆಗಳು ತಮ್ಮ ಪೋಷಕ ವ್ಯಾಪ್ತಿಯಿಂದ ವೇರಿಯೇಬಲ್ಗಳನ್ನು ಸೆರೆಹಿಡಿಯುವಾಗ ನಿಯಂತ್ರಣ ಹರಿವು ರೇಖಾತ್ಮಕವಲ್ಲದ ಮತ್ತು ವಿಶ್ಲೇಷಿಸಲು ಹೆಚ್ಚು ಕಷ್ಟಕರವಾಗುತ್ತದೆ. ಇದನ್ನು ಪರಿಗಣಿಸಿ:
function process(value: string | null) {
if (value === null) {
return;
}
// ಈ ಹಂತದಲ್ಲಿ, CFA ಗೆ 'value' ಸ್ಟ್ರಿಂಗ್ ಎಂದು ತಿಳಿದಿದೆ.
setTimeout(() => {
// ಕಾಲ್ಬ್ಯಾಕ್ ಒಳಗೆ, ಇಲ್ಲಿ 'value' ನ ಪ್ರಕಾರ ಯಾವುದು?
console.log(value.toUpperCase()); // ಇದು ಸುರಕ್ಷಿತವೇ?
}, 1000);
}
ಇದು ಸುರಕ್ಷಿತವೇ? ಇದು ಅವಲಂಬಿಸಿರುತ್ತದೆ. ಪ್ರೋಗ್ರಾಂನ ಇನ್ನೊಂದು ಭಾಗವು `setTimeout` ಕರೆ ಮತ್ತು ಅದರ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯ ನಡುವೆ `value` ಅನ್ನು ಮಾರ್ಪಡಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಹೊಂದಿದ್ದರೆ, ಕಿರಿದಾಗಿಸುವಿಕೆ ಅಮಾನ್ಯವಾಗುತ್ತದೆ. ಟೈಪ್ಸ್ಕ್ರಿಪ್ಟ್ನಂತಹ ಹೆಚ್ಚಿನ ಟೈಪ್ ಚೆಕರ್ಗಳು ಇಲ್ಲಿ ಸಂಪ್ರದಾಯವಾದಿಗಳಾಗಿವೆ. ಬದಲಾಯಿಸಬಹುದಾದ ಮುಚ್ಚುವಿಕೆಯಲ್ಲಿ ಸೆರೆಹಿಡಿಯಲಾದ ವೇರಿಯೇಬಲ್ ಬದಲಾಗಬಹುದು ಎಂದು ಅವರು ಭಾವಿಸುತ್ತಾರೆ, ಆದ್ದರಿಂದ ಹೊರಗಿನ ವ್ಯಾಪ್ತಿಯಲ್ಲಿ ಮಾಡಿದ ಕಿರಿದಾಗಿಸುವಿಕೆಯು ವೇರಿಯೇಬಲ್ `const` ಆಗಿರದ ಹೊರತು ಕಾಲ್ಬ್ಯಾಕ್ನೊಳಗೆ ಕಳೆದುಹೋಗುತ್ತದೆ.
`never` ನೊಂದಿಗೆ ದಣಿವರಿತ ಪರಿಶೀಲನೆ
CFA ಯ ಅತ್ಯಂತ ಶಕ್ತಿಯುತ ಅನ್ವಯಿಕೆಗಳಲ್ಲಿ ಒಂದಾದ ದಣಿವರಿತ ಪರಿಶೀಲನೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುವುದು. `never` ಪ್ರಕಾರವು ಎಂದಿಗೂ ಸಂಭವಿಸಬಾರದ ಮೌಲ್ಯವನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತದೆ. ತಾರತಮ್ಯದ ಯೂನಿಯನ್ನ ಮೇಲಿನ `switch` ಹೇಳಿಕೆಯಲ್ಲಿ, ನೀವು ಪ್ರತಿ ಪ್ರಕರಣವನ್ನು ನಿರ್ವಹಿಸುವಾಗ, CFA ನಿರ್ವಹಿಸಿದ ಪ್ರಕರಣವನ್ನು ಕಳೆಯುವ ಮೂಲಕ ವೇರಿಯೇಬಲ್ನ ಪ್ರಕಾರವನ್ನು ಕಿರಿದಾಗಿಸುತ್ತದೆ.
function getArea(shape: Shape) { // Shape is Circle | Square
switch (shape.kind) {
case 'circle':
// ಇಲ್ಲಿ, ಆಕಾರವು ವೃತ್ತವಾಗಿದೆ
return Math.PI * shape.radius ** 2;
case 'square':
// ಇಲ್ಲಿ, ಆಕಾರವು ಚೌಕವಾಗಿದೆ
return shape.sideLength ** 2;
default:
// ಇಲ್ಲಿ 'shape' ನ ಪ್ರಕಾರ ಯಾವುದು?
// ಇದು (Circle | Square) - Circle - Square = ಎಂದಿಗೂ ಅಲ್ಲ
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
ನಂತರ ನೀವು `Triangle` ಅನ್ನು `Shape` ಯೂನಿಯನ್ಗೆ ಸೇರಿಸಿದರೆ ಆದರೆ ಅದಕ್ಕಾಗಿ `case` ಅನ್ನು ಸೇರಿಸಲು ಮರೆತರೆ, `default` ಶಾಖೆಯನ್ನು ತಲುಪಬಹುದು. ಆ ಶಾಖೆಯಲ್ಲಿನ `shape` ನ ಪ್ರಕಾರವು `Triangle` ಆಗಿರುತ್ತದೆ. `Triangle` ಅನ್ನು `never` ಪ್ರಕಾರದ ವೇರಿಯೇಬಲ್ಗೆ ನಿಯೋಜಿಸಲು ಪ್ರಯತ್ನಿಸುವುದರಿಂದ ಕಂಪೈಲ್-ಸಮಯದ ದೋಷ ಉಂಟಾಗುತ್ತದೆ, ನಿಮ್ಮ `switch` ಹೇಳಿಕೆಯು ಇನ್ನು ಮುಂದೆ ದಣಿವರಿತವಾಗಿಲ್ಲ ಎಂದು ತಕ್ಷಣ ನಿಮಗೆ ಎಚ್ಚರಿಕೆ ನೀಡುತ್ತದೆ. ಇದು ಅಪೂರ್ಣ ತರ್ಕದ ವಿರುದ್ಧ ಬಲವಾದ ಸುರಕ್ಷತಾ ನಿವ್ವಳವನ್ನು ಒದಗಿಸುವ CFA ಆಗಿದೆ.
ಡೆವಲಪರ್ಗಳಿಗೆ ಪ್ರಾಯೋಗಿಕ ಪರಿಣಾಮಗಳು
CFA ತತ್ವಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ನಿಮ್ಮನ್ನು ಹೆಚ್ಚು ಪರಿಣಾಮಕಾರಿ ಪ್ರೋಗ್ರಾಮರ್ ಆಗಿ ಮಾಡಬಹುದು. ನೀವು ಸರಿಯಾಗಿರುವ ಕೋಡ್ ಅನ್ನು ಮಾತ್ರ ಬರೆಯಬಹುದು, ಆದರೆ ಟೈಪ್ ಚೆಕರ್ನೊಂದಿಗೆ 'ಚೆನ್ನಾಗಿ ಆಡುತ್ತದೆ', ಇದು ಸ್ಪಷ್ಟವಾದ ಕೋಡ್ ಮತ್ತು ಕಡಿಮೆ ಪ್ರಕಾರ-ಸಂಬಂಧಿತ ಯುದ್ಧಗಳಿಗೆ ಕಾರಣವಾಗುತ್ತದೆ.
- ಊಹಿಸಬಹುದಾದ ಕಿರಿದಾಗಿಸುವಿಕೆಗಾಗಿ `const` ಅನ್ನು ಆದ್ಯತೆ ನೀಡಿ: ವೇರಿಯೇಬಲ್ ಅನ್ನು ಮರುನಿಯೋಜಿಸಲು ಸಾಧ್ಯವಾಗದಿದ್ದಾಗ, ವಿಶ್ಲೇಷಕವು ಅದರ ಪ್ರಕಾರದ ಬಗ್ಗೆ ಬಲವಾದ ಖಾತರಿಗಳನ್ನು ನೀಡಬಹುದು. `let` ಗಿಂತ `const` ಅನ್ನು ಬಳಸುವುದು ಮುಚ್ಚುವಿಕೆಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಹೆಚ್ಚು ಸಂಕೀರ್ಣ ವ್ಯಾಪ್ತಿಗಳಲ್ಲಿ ಕಿರಿದಾಗಿಸುವಿಕೆಯನ್ನು ಸಂರಕ್ಷಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ.
- ತಾರತಮ್ಯದ ಯೂನಿಯನ್ಗಳನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳಿ: ಅಕ್ಷರಶಃ ಆಸ್ತಿಯೊಂದಿಗೆ (like `kind` ಅಥವಾ `type`) ನಿಮ್ಮ ಡೇಟಾ ರಚನೆಗಳನ್ನು ವಿನ್ಯಾಸಗೊಳಿಸುವುದು CFA ಸಿಸ್ಟಮ್ಗೆ ಉದ್ದೇಶವನ್ನು ಸೂಚಿಸಲು ಅತ್ಯಂತ ಸ್ಪಷ್ಟ ಮತ್ತು ಶಕ್ತಿಯುತ ಮಾರ್ಗವಾಗಿದೆ. ಈ ಯೂನಿಯನ್ಗಳ ಮೇಲಿನ `switch` ಹೇಳಿಕೆಗಳು ಸ್ಪಷ್ಟವಾಗಿವೆ, ಪರಿಣಾಮಕಾರಿಯಾಗಿವೆ ಮತ್ತು ದಣಿವರಿತ ಪರಿಶೀಲನೆಗೆ ಅವಕಾಶ ನೀಡುತ್ತವೆ.
- ನೇರ ತಪಾಸಣೆಗಳನ್ನು ಇರಿಸಿ: ಅಲಿಯಾಸಿಂಗ್ನೊಂದಿಗೆ ನೋಡಿದಂತೆ, ಆಸ್ತಿಯನ್ನು ಸ್ಥಳೀಯ ವೇರಿಯೇಬಲ್ಗೆ ನಕಲಿಸುವುದಕ್ಕಿಂತ ಮತ್ತು ಅದನ್ನು ಪರಿಶೀಲಿಸುವುದಕ್ಕಿಂತ ವಸ್ತುವಿನ ಮೇಲೆ ನೇರವಾಗಿ ಆಸ್ತಿಯನ್ನು ಪರಿಶೀಲಿಸುವುದು (`obj.prop`) ಕಿರಿದಾಗಿಸಲು ಹೆಚ್ಚು ವಿಶ್ವಾಸಾರ್ಹವಾಗಿದೆ.
- CFA ಅನ್ನು ಗಮನದಲ್ಲಿಟ್ಟುಕೊಂಡು ಡೀಬಗ್ ಮಾಡಿ: ನೀವು ಪ್ರಕಾರದ ದೋಷವನ್ನು ಎದುರಿಸಿದಾಗ, ಒಂದು ಪ್ರಕಾರವನ್ನು ಕಿರಿದಾಗಿಸಬೇಕೆಂದು ನೀವು ಭಾವಿಸಿದರೆ, ನಿಯಂತ್ರಣ ಹರಿವಿನ ಬಗ್ಗೆ ಯೋಚಿಸಿ. ವೇರಿಯೇಬಲ್ ಅನ್ನು ಬೇರೆಡೆ ಮರುನಿಯೋಜಿಸಲಾಗಿದೆಯೇ? ವಿಶ್ಲೇಷಕವು ಸಂಪೂರ್ಣವಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗದ ಮುಚ್ಚುವಿಕೆಯೊಳಗೆ ಅದನ್ನು ಬಳಸಲಾಗುತ್ತಿದೆಯೇ? ಈ ಮಾನಸಿಕ ಮಾದರಿಯು ಪ್ರಬಲವಾದ ಡೀಬಗ್ ಮಾಡುವ ಸಾಧನವಾಗಿದೆ.
ತೀರ್ಮಾನ: ಪ್ರಕಾರದ ಸುರಕ್ಷತೆಯ ಮೌನ ರಕ್ಷಕ
ಟೈಪ್ ಕಿರಿದಾಗಿಸುವಿಕೆ ಅರ್ಥಗರ್ಭಿತವಾಗಿ, ಬಹುತೇಕ ಮ್ಯಾಜಿಕ್ನಂತೆ ಭಾಸವಾಗುತ್ತದೆ, ಆದರೆ ಇದು ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆಯ ಮೂಲಕ ಜೀವಂತವಾಗಿ ತರಲಾದ ಕಂಪೈಲರ್ ಸಿದ್ಧಾಂತದಲ್ಲಿ ದಶಕಗಳ ಸಂಶೋಧನೆಯ ಉತ್ಪನ್ನವಾಗಿದೆ. ಪ್ರೋಗ್ರಾಂನ ಕಾರ್ಯಗತಗೊಳಿಸುವ ಮಾರ್ಗಗಳ ಗ್ರಾಫ್ ಅನ್ನು ನಿರ್ಮಿಸುವ ಮೂಲಕ ಮತ್ತು ಪ್ರತಿ ಅಂಚಿನಲ್ಲಿ ಮತ್ತು ಪ್ರತಿ ವಿಲೀನ ಬಿಂದುವಿನಲ್ಲಿ ಪ್ರಕಾರದ ಮಾಹಿತಿಯನ್ನು ನಿಖರವಾಗಿ ಟ್ರ್ಯಾಕ್ ಮಾಡುವ ಮೂಲಕ, ಟೈಪ್ ಚೆಕರ್ಗಳು ಗಮನಾರ್ಹ ಮಟ್ಟದ ಬುದ್ಧಿವಂತಿಕೆ ಮತ್ತು ಸುರಕ್ಷತೆಯನ್ನು ಒದಗಿಸುತ್ತವೆ.
CFA ಎಂಬುದು ಮೌನ ರಕ್ಷಕವಾಗಿದ್ದು ಅದು ಯೂನಿಯನ್ಗಳು ಮತ್ತು ಇಂಟರ್ಫೇಸ್ಗಳಂತಹ ಹೊಂದಿಕೊಳ್ಳುವ ಪ್ರಕಾರಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ನಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ ಮತ್ತು ಅವು ಉತ್ಪಾದನೆಗೆ ತಲುಪುವ ಮೊದಲು ದೋಷಗಳನ್ನು ಹಿಡಿಯುತ್ತದೆ. ಇದು ಸ್ಥಿರ ಟೈಪಿಂಗ್ ಅನ್ನು ಕಟ್ಟುನಿಟ್ಟಾದ ನಿರ್ಬಂಧಗಳ ಗುಂಪಿನಿಂದ ಡೈನಾಮಿಕ್, ಸಂದರ್ಭ-ಅರಿವಿನ ಸಹಾಯಕವಾಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ. ಮುಂದಿನ ಬಾರಿ ನಿಮ್ಮ ಸಂಪಾದಕವು `if` ಬ್ಲಾಕ್ನಲ್ಲಿ ಪರಿಪೂರ್ಣ ಸ್ವಯಂಪೂರ್ಣತೆಯನ್ನು ಒದಗಿಸಿದರೆ ಅಥವಾ `switch` ಹೇಳಿಕೆಯಲ್ಲಿ ನಿರ್ವಹಿಸದ ಪ್ರಕರಣವನ್ನು ಗುರುತಿಸಿದರೆ, ಅದು ಮ್ಯಾಜಿಕ್ ಅಲ್ಲ ಎಂದು ನಿಮಗೆ ತಿಳಿಯುತ್ತದೆ - ಇದು ನಿಯಂತ್ರಣ ಹರಿವಿನ ವಿಶ್ಲೇಷಣೆಯ ಸೊಗಸಾದ ಮತ್ತು ಶಕ್ತಿಯುತ ತರ್ಕವಾಗಿದೆ.